/*
 * Copyright (c) 2001, 2002 Boris Pruessmann and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v0.5
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 *    Boris Pruessmann - Initial implementation.
 */
package net.sourceforge.perforce.core.internal.api;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import net.sourceforge.perforce.api.IPerforceCommand;
import net.sourceforge.perforce.core.PerforceCorePlugin;
import net.sourceforge.perforce.core.api.IDescribeResult;
import net.sourceforge.perforce.core.syncinfo.ResourceSyncInfo;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;

/**
  * ClientUser object for the 'p4 describe' command.
  * 
  * @version $Revision: 26 $
  * @author <a href="mailto:bpruessmann@users.sourceforge.net">Boris Pruessmann</a>
  */
public class Describe extends AbstractPerforceCommand implements IPerforceCommand
{
	// --------------------------------------------------------------------------- Private Variables
	
	/** Stores the result of the operation. */
	private Result result = new Result();

	// --------------------------------------------------------------- Public Static Factory Methods
	
	/** Convenience method for creating instances of Describe.
	  * 
	  * @return the new Describe instance.
	  */
	public static final Describe newInstance()
	{
		MultiStatus status = new MultiStatus(PerforceCorePlugin.ID, IStatus.OK, "", null);
		return new Describe(status);
	}

	// ------------------------------------------------------------------------ Private Constructors
 
	/** Constructor for Describe. 
	  * 
	  * @param status the MultiStatus.
	  */
	private Describe(MultiStatus status)
	{		
		super(status);
	}

	// -------------------------------------------------------- Public Methods (IClientUserDelegate)
	
	/** @see IClientUserDelegate#outputStat(Map) */
	public void outputStat(Map strDict)
	{
		result.setChangelist(Helper.safeGetInteger(strDict, "change"));                //$NON-NLS-1$
		result.setUserName(Helper.safeGetString(strDict, "user"));                     //$NON-NLS-1$
		result.setClientName(Helper.safeGetString(strDict, "client"));                 //$NON-NLS-1$
		result.setDate(Helper.safeGetDate(strDict, "time"));                           //$NON-NLS-1$
		result.setDescription(Helper.safeGetString(strDict, "desc"));                  //$NON-NLS-1$
		result.setStatus(Helper.safeGetString(strDict, "status"));                     //$NON-NLS-1$
		
		List affectedFiles = new ArrayList();		
		for (int i = 0; strDict.containsKey("depotFile" + i); i++)                     //$NON-NLS-1$
		{
			ResourceSyncInfo resourceSyncInfo = new ResourceSyncInfo();
			resourceSyncInfo.setDepotFileName(
				Helper.safeGetString(strDict, "depotFile" + i));                       //$NON-NLS-1$
			resourceSyncInfo.setAction(Helper.safeGetString(strDict, "action" + i));   //$NON-NLS-1$
			resourceSyncInfo.setHeadType(Helper.safeGetString(strDict, "type" + i));   //$NON-NLS-1$
			resourceSyncInfo.setHeadRev(Helper.safeGetInteger(strDict, "rev" + i));    //$NON-NLS-1$
			
			affectedFiles.add(resourceSyncInfo);
		}
		
		result.setAffectedFiles(
			(ResourceSyncInfo[]) affectedFiles.toArray(new ResourceSyncInfo[affectedFiles.size()]));
	}

	// ----------------------------------------------------------- Public Methods (IPerforceCommand)

	/** @see IPerforceCommand#getCommand() */
	public String getCommand()
	{
		return "describe";                                                             //$NON-NLS-1$
	}

	/** @see IPerforceCommand#getStatus() */
	public IStatus getStatus()
	{
		return getMultiStatus();
	}
	
	/** @see IPerforceCommand#isHidingFromConsole() */
	public boolean isHidingFromConsole()
	{
		return false;
	}

	// ------------------------------------------------------------------------------ Public Methods
	
	/** Returns the result of the operation.
	  * 
	  * @return the result object.
	  */
	public IDescribeResult getResult()
	{
		return result;
	}

	// ---------------------------------------------------------------------- Private Nested Classes
		
	/**
	  * Implementation of the IDescribeResult. Stores information provided
	  * by the 'p4 describe' command.
	  * 
	  * @see IDescribeResult
	  */
	private static class Result implements IDescribeResult
	{
		// ----------------------------------------------------------------------- Private Variables
		
		/** Stores the changelist number. */
		private Integer changelist;
		/** Stores the username. */
		private String userName;
		/** Stores the client name. */
		private String clientName;
		/** Stores the submission date. */
		private Date date;
		/** Stores the description. */
		private String description;
		/** Stores the status. */
		private String status;
		/** Stores the affected files. */
		private ResourceSyncInfo[] affectedFiles;

		// -------------------------------------------------------------------------- Public Methods
	
		/** @see IDescribeResult#getChangelist() */
		public Integer getChangelist() 
		{ 
			return changelist; 
		}
	
		/** @see IDescribeResult#getUsernName() */
		public String getUserName()
		{ 
			return userName; 
		}
		
		/** @see IDescribeResult#getClientName() */
		public String getClientName() 
		{	
			return clientName; 
		}
	
		/** @see IDescribeResult#getDate() */
		public Date getDate() 
		{ 
			return date; 
		}
	
		/** @see IDescribeResult#getDescription() */
		public String getDescription() 
		{ 
			return description; 
		}
	
		/** @see IDescribeResult#getStatus() */
		public String getStatus() 
		{ 
			return status; 
		}
		
		/** @see IDescribeResult#getAffectedFiles() */
		public ResourceSyncInfo[] getAffectedFiles() 
		{ 
			return affectedFiles; 
		}
		
		// --------------------------------------------------------------------------------- Methods

		/** Sets the affectedFiles.
		  * 
		  * @param affectedFiles The affectedFiles to set
		  */
		void setAffectedFiles(ResourceSyncInfo[] affectedFiles) 
		{
			this.affectedFiles = affectedFiles;
		}

		/** Sets the changelist.
		  * 
		  * @param changelist The changelist to set
		  */
		void setChangelist(Integer changelist) 
		{
			this.changelist = changelist;
		}

		/** Sets the clientName.
		  * 
		  * @param clientName The clientName to set
		  */
		void setClientName(String clientName) 
		{
			this.clientName = clientName;
		}

		/** Sets the date.
		  * 
		  * @param date The date to set
		  */
		void setDate(Date date) 
		{
			this.date = date;
		}

		/** Sets the description.
		  * 
		  * @param description The description to set
		  */
		void setDescription(String description) 
		{
			this.description = description;
		}

		/** Sets the status.
		  * 
		  * @param status The status to set
		  */
		void setStatus(String status) 
		{
			this.status = status;
		}

		/** Sets the userName.
		  * 
		  * @param userName The userName to set
		  */
		void setUserName(String userName) 
		{
			this.userName = userName;
		}
	}	
}
